#include "hal_EEpromWR.h"
#include "i2c.h"
#include <cfg_param.h>
#include <common.h>
#include "hal_tlv.h"

HAL_StatusTypeDef eeprom_state_out = HAL_OK;

uint8_t HAL_I2cEEPromRead(uint16_t StartAddress, uint8_t *RealData, uint16_t SizeData)
{
    // 一次性读取需要的所有数据
    HAL_StatusTypeDef eeprom_state = HAL_I2C_Mem_Read(&hi2c3, EEPROM_ADDRESS_READ, StartAddress,
                                                      (MODEL_CHOICE == MODEL_MOTOR) ? I2C_MEMADD_SIZE_16BIT : I2C_MEMADD_SIZE_8BIT, // ATC02：8位，ATC128：16位
                                                      (uint8_t *)RealData, SizeData, I2C3_TIMEOUT_MULTIPLIER);

    return eeprom_state;
}

uint8_t HAL_I2cEEPromWrite(uint16_t StartAddress, uint8_t *WriteData, uint16_t SizeData)
{
    HAL_StatusTypeDef eeprom_state = HAL_OK;
    uint16_t remaining_size        = SizeData;

    // 写保护关闭，EEPROM可写
    HAL_GPIO_WritePin(EEPROM_WP_GPIO_Port, EEPROM_WP_Pin, GPIO_PIN_RESET);

    uint16_t PAGESIZE = (MODEL_CHOICE == MODEL_MOTOR) ? ATC128_PAGE_SIZE : ATC02_PAGE_SIZE;

    // 按照每次写入N个字节的方式进行多次写入
    // ATC02：2K字节，总共16页，每页16字节，每次可以最多直接写入16个字节
    // ATC128：128K字节，总共256页，每页64字节，每次最多可以直接写入64个字节
    while (remaining_size > 0)
    {
        // 计算当前页内的剩余空间
        uint16_t page_offset       = StartAddress % PAGESIZE;
        uint16_t remaining_in_page = PAGESIZE - page_offset;

        // 计算当前写入大小
        uint16_t current_write_size = (remaining_size > remaining_in_page) ? remaining_in_page : remaining_size;

        // 执行 I2C 写入
        eeprom_state = HAL_I2C_Mem_Write(&hi2c3, EEPROM_ADDRESS_WRITE, StartAddress,
                                         (MODEL_CHOICE == MODEL_MOTOR) ? I2C_MEMADD_SIZE_16BIT : I2C_MEMADD_SIZE_8BIT, // ATC02：8位，ATC128：16位
                                         WriteData, current_write_size, I2C3_TIMEOUT_MULTIPLIER);

        systick_delay_ms(5);

        if (eeprom_state != HAL_OK)
        {
					eeprom_state_out = eeprom_state;
            break;
        }

        // 更新地址和剩余字节数
        StartAddress += current_write_size;
        WriteData += current_write_size;
        remaining_size -= current_write_size;
    }

    // 写保护打开，EEPROM不可写
    HAL_GPIO_WritePin(EEPROM_WP_GPIO_Port, EEPROM_WP_Pin, GPIO_PIN_SET);

    return eeprom_state;
}
